#include <modules\system\win32\win32_system_window.h>

namespace DelGE
{
	namespace Modules
	{
		namespace System
		{
			Win32SystemWindow::Win32SystemWindow(string sCaption, int iWidth, int iHeight, DelGESystemWindowStyle eStyle)
			{
				HINSTANCE hInstance;
				DWORD style;

				hInstance = GetModuleHandle(NULL);

				switch (eStyle)
				{
				case DelGESystemWindowStyle_FixedSize:
					style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
					break;

				case DelGESystemWindowStyle_Frameless:
					style = WS_POPUP | WS_MAXIMIZE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
					break;
				}
				this->eStyle = eStyle;

				this->hWnd = CreateWindowEx(0, "windowClass", sCaption.c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT, iWidth, iHeight, NULL, NULL, hInstance, NULL);
				SetWindowPos(this->hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);

				if (this->hWnd)
				{
					this->SetSize(iWidth, iHeight);

					ShowWindow(this->hWnd, true);
					UpdateWindow(this->hWnd);

					this->hDC = GetDC(this->hWnd);

					SetWindowLong(this->hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
				}

				this->bIsMouseInside = false;
			}

			Win32SystemWindow::~Win32SystemWindow()
			{
				ReleaseDC(this->hWnd, this->hDC);
				DestroyWindow(this->hWnd);

				this->bIsMouseInside = false;
			}

			void Win32SystemWindow::SetCaption(string sCaption)
			{
				SetWindowText(this->hWnd, sCaption.c_str());
			}

			string Win32SystemWindow::GetCaption()
			{
				char* pText = new char[GetWindowTextLength(this->hWnd) + 1];
				GetWindowText(this->hWnd, pText, GetWindowTextLength(this->hWnd) + 1);
				string sText = string(pText);
				delete pText;
				return sText;
			}

			void Win32SystemWindow::Show()
			{
				ShowWindow(this->hWnd, true);
				this->bClosed = false;
			}

			void Win32SystemWindow::Hide()
			{
				ShowWindow(this->hWnd, false);
				this->bClosed = true;
			}

			void Win32SystemWindow::SetStyle(DelGESystemWindowStyle eStyle)
			{
				DWORD style;

				style = GetWindowLong(this->hWnd, GWL_STYLE);

				switch (this->eStyle)
				{
					case DelGESystemWindowStyle_FixedSize:
						if (this->eStyle != eStyle)
						{
							style = style & ~(WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
							if (eStyle == DelGESystemWindowStyle_Frameless)
								style = style | (WS_POPUP | WS_MAXIMIZE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
						}
						break;

					case DelGESystemWindowStyle_Frameless:
						if (this->eStyle != eStyle)
						{
							style = style & ~(WS_POPUP | WS_MAXIMIZE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
							if (eStyle == DelGESystemWindowStyle_FixedSize)
								style = style | (WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
						}
						break;
				}

				this->eStyle = eStyle;
				
				SetWindowLong(this->hWnd, GWL_STYLE, style);
				SetWindowPos(this->hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
				ShowWindow(this->hWnd, TRUE);

				this->SetSize(this->GetWidth(), this->GetHeight());
			}

			DelGESystemWindowStyle Win32SystemWindow::GetStyle()
			{
				return this->eStyle;
			}

			bool Win32SystemWindow::IsClosed()
			{
				return this->bClosed;
			}			
		}
	}
}